package main

import (
	"encoding/json"
	"fmt"
)

type IT struct {
	Company string	`json:"company"`
	Subjects []string `json:"subjects"`
	IsOk bool `json:"is_ok,string"`
	Price float64 `json:"price,omitempty"`
	Abc string `json:"-"`
}

/*
struct tag
1.字段的tag是"-",那么该字段不会输出到json
2.tag中带有自定义名称,那么这个自定义名称会出现在json的字段名中
3.tag中如果带有"omitempty"选项,那么如果该字段值为空,就不会输出到json中
4.如果字段类似是bool,string,int,int64等,而tag中带有",string"选项,那么这个字段在输出到json中会把该字段转换为字符串
 */

func main () {
	//json编码
	t := IT{Company:"itcast", Subjects:[]string{"go", "c++", "js"}, IsOk:true, Price:12.1, Abc:"abc"}
	//进行json编码
	j, err := json.Marshal(t)

	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(string(j))

	t1 := make(map[string]interface{})
	t1["company"] = "itcast"
	t1["subjects"] = []string{"Go", "C++", "Python"}
	t1["is_ok"] = true
	t1["price"] = 66.32
	b, err := json.Marshal(t1)
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(string(b))

	//json解码
	var t2 IT
	err = json.Unmarshal(j, &t2)
	if err != nil {
		fmt.Println("json decode:error", err)
	}

	fmt.Println(t2)

	//只要某个字段
	type IT2 struct {
		Subjects []string `json:"subjects"`
	}

	var t3 IT2
	err = json.Unmarshal(j, &t3)

	if err != nil {
		fmt.Println("json decode:error", err)
	}

	fmt.Println(t3)

	//解析到interface{}
	var t4 interface{}
	err = json.Unmarshal(j, &t4)
	if err != nil {
		fmt.Println("json decode:error", err)
	}

	fmt.Println(t4)

	//必须断言才行
	m := t4.(map[string]interface{})
	for k,v := range m {
		switch vv := v.(type) {
		case string:
			fmt.Println(k, "is string ", vv)
		case int:
			fmt.Println(k, "is int ", vv)
		case float64:
			fmt.Println(k, "is float64 ", vv)
		case bool:
			fmt.Println(k, "is bool ", vv)
		case []interface{}:
			fmt.Println(k, "is an array:")
			for i, u := range vv {
				fmt.Println(i, u)
			}
		default:
			fmt.Println(k, "is of a type I don't know how to handle")

		}
	}
}
